#region Microsoft Public License
/*
 * (c) Copyright Chenjun Wu. http://utablesdk.codeplex.com
 * 
 * This source is subject to the Microsoft Public License (Ms-PL).
 * Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
 * All other rights reserved.
 */
#endregion

﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media;

namespace UTable.Objects.Controls
{
	public class UScanView: ItemsControl, IControl
	{
		#region Private Fields

		private int _currentItemIndex = 0;

		private UScanViewPanel _panel = null;

		#endregion

		#region Private Methods

		private static void OnLayoutPropertiesChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
		{
			(obj as UScanView).OnLayoutPropertiesChanged();
		}

		private void OnLayoutPropertiesChanged()
		{
			if (_panel != null)
				_panel.OnDirectionChanged();
		}

		#endregion

		#region Constructors

		static UScanView()
        {
			DefaultStyleKeyProperty.OverrideMetadata(typeof(UScanView), new FrameworkPropertyMetadata(typeof(UScanView)));
        }

		public UScanView()
        {
            InitializeIControlPart();
			this.Loaded += new RoutedEventHandler(UPieView_Loaded);
        }

		void UPieView_Loaded(object sender, RoutedEventArgs e)
		{
			ItemsPresenter p = this.GetTemplateChild("PART_ItemsPresenter") as ItemsPresenter;
			_panel = VisualTreeHelper.GetChild(p, 0) as UScanViewPanel;
			_panel.ScanView = this;
			_panel.InitializeMultiTouchProcessorPart();
			_panel.ArrangeChildren();
		}

		#endregion

		#region Properties

		public int CurrentItemIndex
		{
			get
			{
				if (_panel != null)
					return _panel.CurrentItemIndex;
				else
					return -1;
			}
			set
			{
				JumpTo(value);
			}
		}

		public UScanViewTurnDirectionType TurnDirection
		{
			get { return (UScanViewTurnDirectionType)GetValue(TurnDirectionProperty); }
			set { SetValue(TurnDirectionProperty, value); }
		}

		public static readonly DependencyProperty TurnDirectionProperty =
			DependencyProperty.Register("TurnDirection", typeof(UScanViewTurnDirectionType), typeof(UScanView), new UIPropertyMetadata(UScanViewTurnDirectionType.LeftRight, new PropertyChangedCallback(OnLayoutPropertiesChanged)));

		#endregion

		#region Public Methods

		public void JumpTo(int index)
		{
			if (_panel != null)
				_panel.JumpTo(index);
		}

		public void TurnPrevious()
		{
			if (_panel != null)
				_panel.TurnPrevious();
		}

		public void TurnNext()
		{
			if (_panel != null)
				_panel.TurnNext();
		}

		#endregion

		#region Protected Methods

		public override void OnApplyTemplate()
		{
			base.OnApplyTemplate();
		}

		protected override void OnItemsPanelChanged(ItemsPanelTemplate oldItemsPanel, ItemsPanelTemplate newItemsPanel)
		{
			base.OnItemsPanelChanged(oldItemsPanel, newItemsPanel);
		}

		protected override void OnItemsSourceChanged(System.Collections.IEnumerable oldValue, System.Collections.IEnumerable newValue)
		{
			base.OnItemsSourceChanged(oldValue, newValue);
		}

		protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
		{
			base.PrepareContainerForItemOverride(element, item);
		}

		protected override bool IsItemItsOwnContainerOverride(object item)
		{
			if (item is UScanViewItem)
				return true;
			else
				return false;
		}

		protected override DependencyObject GetContainerForItemOverride()
		{
			return new UScanViewItem();
		}

		#endregion

		#region IControl Implementation
		
		#region Private Fields

        private ControlBaseImpl _impl;

        #endregion

		#region Private Methods

		private void InitializeIControlPart()
        {
			_impl = new ControlBaseImpl(this);
            _impl.GotFingerCapture += new UTable.Input.MultiTouch.FingerEventHandler(_impl_GotFingerCapture);
            _impl.LostFingerCapture += new UTable.Input.MultiTouch.FingerEventHandler(_impl_LostFingerCapture);
			this.InputReceived += new UTable.Input.InputEventHandler(_impl_InputReceived);
        }

        void _impl_InputReceived(UTable.Input.InputEventArgs args)
        {
			if (args is UTable.Input.MultiTouch.MultiTouchEventArgs)
				MultiTouchProcessor.RaiseMultiTouchEvent(args as UTable.Input.MultiTouch.MultiTouchEventArgs);
        }

        void _impl_LostFingerCapture(object sender, UTable.Input.MultiTouch.FingerEventArgs args)
        {
            if (LostFingerCapture != null)
                LostFingerCapture(sender, args);
        }

        void _impl_GotFingerCapture(object sender, UTable.Input.MultiTouch.FingerEventArgs args)
        {
            if (GotFingerCapture != null)
                GotFingerCapture(sender, args);
        }

        #endregion

        #region IControl Members

        public UTable.Objects.Controls.ControlInfo Info
        {
            get { return _impl.Info; }
        }
		
		public UTable.Objects.Handlers.MultiTouchProcessor MultiTouchProcessor 
		{ 
			get { return _impl.MultiTouchProcessor; } 
		}

        #endregion

        #region IVisualNode Members

        public String ID
        {
            get { return _impl.ID; }
        }

        public new double Width
        {
            get { return _impl.Width; }
            set { _impl.Width = value; }
        }

        public new double Height
        {
            get { return _impl.Height; }
            set { _impl.Height = value; }
        }

        public new bool IsHitTestVisible
        {
            get { return _impl.IsHitTestVisible; }
            set { _impl.IsHitTestVisible = value; }
        }

        #endregion

        #region IInputNode Members

        public void RaiseEvent(UTable.Input.InputEventArgs e)
        {
            if (InputReceived != null)
            {
                InputReceived(e);
            }
            OnInputReceived(e);
        }

        public virtual void OnInputReceived(UTable.Input.InputEventArgs args)
        {
            _impl.OnInputReceived(args);
        }

        public bool CaptureFinger(int fingerId)
        {
            return _impl.CaptureFinger(fingerId);
        }

        public bool UncaptureFinger(int fingerId)
        {
            return _impl.UncaptureFinger(fingerId);
        }

        public event UTable.Input.MultiTouch.FingerEventHandler GotFingerCapture;

        public event UTable.Input.MultiTouch.FingerEventHandler LostFingerCapture;

        public event UTable.Input.InputEventHandler InputReceived;

        #endregion
        #endregion
	}

	public enum UScanViewTurnDirectionType
	{
		LeftRight,
		TopDown,
	}
}
